package com.dd.stack.file.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dd.stack.common.util.Result;
import com.dd.stack.common.util.ResultEnum;
import com.dd.stack.file.pojo.DO.ExcelProductDO;
import com.dd.stack.file.pojo.VO.FileVO;
import com.dd.stack.file.pojo.req.ExcelProductQueryReq;
import com.dd.stack.file.pojo.req.FilePageReq;
import com.dd.stack.file.service.internal.FileService;
import com.dd.stack.file.service.internal.impl.ProductServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.List;

/**
 * @Author liuxianmeng
 * @CreateTime 2024/10/22 22:37
 * @Description 文件处理
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/file")
@Api(tags = "文件操作")
public class FileController {

    @Value("${server.file.download-from-path}")
    private String FILES_DOWNLOAD_FROM_PATH;

    private final FileService fileService;
    private final ProductServiceImpl productService;

    @ApiOperation("文件上传")
    @PostMapping("/upload")
    public Result<?> uploadFile(@ApiParam("要上传的文件") MultipartFile file) {
        try {
            fileService.uploadFile(file);
            return Result.builder().code(ResultEnum.SUCCESS.getCode())
                    .message(ResultEnum.SUCCESS.getMessage()).data(null).build();
        } catch (Exception e) {
            return Result.builder().code(ResultEnum.FAIL.getCode())
                    .message("文件上传失败：" + e.getMessage()).build();
        }
    }

    @PostMapping("/page")
    @ApiOperation("文件多条件范围分页查询")
    public Result<Page<FileVO>> page(@ApiParam("文件多条件范围分页查询请求类") @RequestBody FilePageReq req){
        log.info("FilePageReq req = {}", req);
        return Result.success(ResultEnum.SUCCESS, fileService.page(req));
    }

    @GetMapping("/download/{id}")
    @ApiOperation("下载文件")
    public ResponseEntity<byte[]> downloadFile(@PathVariable Long id) {
        byte[] fileBytes = fileService.downloadFile(id);
        if (fileBytes == null) {
            return ResponseEntity.notFound().build();
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", fileService.getFileNameById(id));
        return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation("传入文件id 删除对应文件")
    public Result<Boolean> deleteFile(@PathVariable Long id) {
        return Result.success(fileService.delete(id));
    }

    /******************************* Excel文件导入导出 START ****************************/

    @ApiOperation("导入商品数据")
    @PostMapping("/import/product")
    public void importProducts(MultipartFile file) {
        try {
            List<ExcelProductDO> productList = EasyExcel
                    .read(file.getInputStream())
                    .head(ExcelProductDO.class)
                    .sheet()
                    .doReadSync();
            // 批量插入
            productService.saveBatch(productList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("导出商品数据")
    @PostMapping("/export/product")
    public ResponseEntity<byte[]> exportProducts(@RequestBody ExcelProductQueryReq queryReq) throws IOException {
        // 1. 生成文件
        String fileName = "products_export.xlsx"; // 仅文件名，不含路径
        File file = new File(FILES_DOWNLOAD_FROM_PATH + File.separator + fileName);

        // 确保目录存在
        File parentDir = file.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            parentDir.mkdirs();
        }

        // 2. 根据查询条件筛选数据
        List<ExcelProductDO> productList = productService.list(queryReq.buildQueryWrapper());

        // 3. 写入Excel数据
        EasyExcel.write(file, ExcelProductDO.class)
                .sheet("产品列表")
                .doWrite(productList);

        // 4. 将文件内容读取为字节数组（确保资源释放）
        byte[] fileContent = Files.readAllBytes(file.toPath());

        // 5. 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment",
                URLEncoder.encode(fileName, "UTF-8").replace("+", "%20"));
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");

        // 6. 返回字节数组而非文件资源
        return ResponseEntity.ok()
                .headers(headers)
                .body(fileContent);
    }

    /******************************* Excel文件导入导出 END ****************************/
}
